package com.sky.his.api.front.service.impl;

import cn.hutool.core.lang.hash.Hash;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.sky.his.api.common.PageUtils;
import com.sky.his.api.db.dao.GoodsDao;
import com.sky.his.api.db.dao.GoodsSnapshotDao;
import com.sky.his.api.db.dao.OrderDao;
import com.sky.his.api.front.service.OrderService;
import com.sky.his.api.front.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("FrontOrderServiceImpl")
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderDao orderDao;

    @Resource
    private GoodsDao goodsDao;

    @Resource
    private RedisTemplate redisTemplate;

    private String paymentNotifyUrl = "/front/order/paymentCallback";

    private String refundNotifyUrl = "/front/order/refundCallback";

    //    @Resource
    private PaymentService paymentService;

    @Resource
    private GoodsSnapshotDao goodsSnapshotDao;


//    @Override
//    @Transactional
//    public HashMap createPayment(Map param) {
//        int goodsId = MapUtil.getInt(param, "goodsId");
//        Integer number = MapUtil.getInt(param, "number");
//        int customerId = MapUtil.getInt(param, "customerId");
//
//        boolean illegal = orderDao.searchIllegalCountInDay(customerId);
//        if (illegal) {
//            return null;
//        }
//        HashMap map = goodsDao.searchSnapshotNeededById(goodsId);
//        String goodsCode = MapUtil.getStr(map, "code");
//        String goodsTitle = MapUtil.getStr(map, "title");
//        String goodsDescription = MapUtil.getStr(map, "description");
//        String goodsImage = MapUtil.getStr(map, "image");
//
//        BigDecimal goodsInitialPrice = new BigDecimal(MapUtil.getStr(map, "initialPrice"));
//        BigDecimal goodsCurrentPrice = new BigDecimal(MapUtil.getStr(map, "currentPrice"));
//        String goodsRuleName = MapUtil.getStr(map, "ruleName");
//        String goodsRule = MapUtil.getStr(map, "rule");
//        String goodsType = MapUtil.getStr(map, "type");
//        String goodsMd5 = MapUtil.getStr(map, "md5");
//
//        String temp = MapUtil.getStr(map, "checkup_1");
//        List<Map> goodsCheckup_1 = temp != null ? JSONUtil.parseArray(temp).toList(Map.class) : null;
//        temp = MapUtil.getStr(map, "checkup_2");
//        List<Map> goodsCheckup_2 = temp != null ? JSONUtil.parseArray(temp).toList(Map.class) : null;
//        temp = MapUtil.getStr(map, "checkup_3");
//        List<Map> goodsCheckup_3 = temp != null ? JSONUtil.parseArray(temp).toList(Map.class) : null;
//        temp = MapUtil.getStr(map, "checkup_4");
//        List<Map> goodsCheckup_4 = temp != null ? JSONUtil.parseArray(temp).toList(Map.class) : null;
//        temp = MapUtil.getStr(map, "checkup");
//        List<Map> goodsCheckup = temp != null ? JSONUtil.parseArray(temp).toList(Map.class) : null;
//        temp = MapUtil.getStr(map, "tag");
//        List<String> goodsTag = temp != null ? JSONUtil.parseArray(temp).toList(String.class) : null;
//
//        ExpressRunner runner = new ExpressRunner();
//        DefaultContext<String, Object> context = new DefaultContext<String, Object>();
//        context.put("number", number.intValue());
//        context.put("price", goodsCurrentPrice.toString());
//
//        String amount = null;
//        if (goodsRule != null) {
//            try {
//                amount = runner.execute(goodsRule, context, null, true, false).toString();
//            } catch (Exception e) {
//                throw new HisException("规则引擎计算价格失败", e);
//            }
//        } else {
//            amount = goodsCurrentPrice.multiply(new BigDecimal(number)).toString();
//        }
//
//        int total = NumberUtil.mul(amount, "100").intValue();
//
//        String outTradeNo = IdUtil.simpleUUID().toUpperCase();
//
//        DateTime dateTime = new DateTime();
//        dateTime.offset(DateField.MINUTE, 20);
//
//        String timeExpire = dateTime.toString("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
//        ObjectNode objectNode = paymentService.unifiedOrder(outTradeNo, total, "购买体检套餐", paymentNotifyUrl, timeExpire);
//
//        String codeUrl = objectNode.get("code_url").textValue();
//
//        String key = "codeUrl_" + customerId + "_" + outTradeNo;
//        redisTemplate.opsForValue().set(key, codeUrl);
//        redisTemplate.expireAt(key, dateTime);
//
//        if (codeUrl != null) {
//            String _id = goodsSnapshotDao.hasGoodsSnapshot(goodsMd5);
//            if (_id != null) {
//                GoodsSnapshotEntity entity = new GoodsSnapshotEntity();
//                entity.setId(goodsId);
//                entity.setCode(goodsCode);
//                entity.setTitle(goodsTitle);
//                entity.setDescription(goodsDescription);
//                entity.setCheckup1(goodsCheckup_1);
//                entity.setCheckup2(goodsCheckup_2);
//                entity.setCheckup3(goodsCheckup_3);
//                entity.setCheckup4(goodsCheckup_4);
//                entity.setImage(goodsImage);
//                entity.setInitialPrice(goodsInitialPrice);
//                entity.setCurrentPrice(goodsCurrentPrice);
//                entity.setType(goodsType);
//                entity.setTag(goodsTag);
//                entity.setRuleName(goodsRuleName);
//                entity.setRule(goodsRule);
//                entity.setCheckup(goodsCheckup);
//                entity.setMd5(goodsMd5);
//
//                _id = goodsSnapshotDao.insert(entity);
//            }
//            OrderEntity entity = new OrderEntity();
//            entity.setCustomerId(customerId);
//            entity.setGoodsId(goodsId);
//            entity.setSnapshotId(_id);
//
//            entity.setGoodsTitle(goodsTitle);
//            entity.setGoodsPrice(goodsCurrentPrice);
//            entity.setNumber(number);
//            entity.setAmount(new BigDecimal(amount));
//            entity.setGoodsDescription(goodsDescription);
//            entity.setOutTradeNo(outTradeNo);
//
//            orderDao.insert(entity);
//
//            QrConfig qrConfig = new QrConfig();
//            qrConfig.setWidth(230);
//            qrConfig.setHeight(230);
//            qrConfig.setMargin(2);
//            String qrCodeBase64 = QrCodeUtil.generateAsBase64(codeUrl, qrConfig, "jpg");
//
//            int rows = goodsDao.updateSalesVolume(goodsId);
//            if (rows != 1) {
//                throw new HisException("更新商品销量失败");
//            }
//            return new HashMap() {
//                {
//                    put("qrCodeBase64", qrCodeBase64);
//                    put("outTradeNo", outTradeNo);
//                }
//            };
//        } else {
//            log.error("创建支付订单失败", objectNode);
//            throw new HisException("创建支付订单失败");
//        }
//    }

    @Override
    @Transactional
    public boolean updatePayment(Map param) {
        int rows = orderDao.updatePayment(param);
        return rows == 1;
    }

    @Override
    public Integer searchCustomerId(String outTradeNo) {
        Integer customerId = orderDao.searchCustomerId(outTradeNo);
        return customerId;
    }

    @Override
    @Transactional
    public boolean searchPaymentResult(String outTradeNo) {
        String transactionId = paymentService.searchPaymentResult(outTradeNo);
        if (transactionId != null) {
            this.updatePayment(new HashMap() {
                {
                    put("outTradeNo", outTradeNo);
                    put("transactionId", transactionId);
                }
            });
            return true;
        }
        return false;
    }

    @Override
    public PageUtils searchByPage(Map param) {
        ArrayList<HashMap> list = new ArrayList<>();
        long count = orderDao.searchFrontOrderCount(param);
        if (count > 0) {
            list = orderDao.searchFrontOrderByPage(param);
        }
        int start = (Integer) param.get("start");
        int length = (Integer) param.get("length");
        PageUtils pageUtils = new PageUtils(list, count, start, length);
        return pageUtils;
    }

    @Override
    public boolean refund(Map param) {
        int id = MapUtil.getInt(param, "id");
        String outRefundNo = orderDao.searchAlreadyRefund(id);

        if (outRefundNo != null) {
            return false;
        }
        HashMap map = orderDao.searchRefundNeeded(param);
        String transactionId = MapUtil.getStr(map, "transactionId");
        String amount = MapUtil.getStr(map, "amount");

        int total = NumberUtil.mul(amount, "100").intValue();
        int refund = 1;

        if (transactionId == null) {
            log.error("transactionId不能为空");
            return false;
        }

        outRefundNo = paymentService.refund(transactionId, refund, total, refundNotifyUrl);
        param.put("outRefundNo", outRefundNo);

        if (outRefundNo != null) {
            int rows = orderDao.updateOutRefundNo(param);
            if (rows == 1) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean updateRefundStatus(String outRefundNo) {
        int rows = orderDao.updateRefundStatusByOutRefundNo(outRefundNo);
        return rows == 1;
    }

    @Override
    public boolean hasOwnOrder(Map param) {
        Integer id = orderDao.hasOwnOrder(param);
        return id != null;
    }
}
